
/*
 *  planet.c
 *  This program shows how to composite modeling transformations
 *  to draw translated and rotated models.
 *  Interaction:  pressing the d and y keys (day and year)
 *  alters the rotation of the planet around the sun.
 */
#include <GL/glut.h>
#include <stdlib.h>

/* stores the offsets for planet1 and planet2 in degrees */
static int year1 = 0, day1 = 0, year2 = 0, day2 = 0, month=0;

/* Amount changed par year and day in degrees */
static int d_year1 = 5, d_day1 = 10, d_year2 = 3, d_day2 = 8;

/* radius used to calcuate view */
static double r=1.0;

void init(void) 
{
   glClearColor (0.0, 0.0, 0.0, 0.0);
   glShadeModel (GL_FLAT);
}

void display(void)
{
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();

   glFrustum(-r, r, -r, r, 1, 20);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   glClear (GL_COLOR_BUFFER_BIT);
   glColor3f (1.0, 1.0, 1.0);


   glPushMatrix();
       glTranslatef (0.0, 0.0, -10.0);
       /* draw sun */
       glutWireSphere(1.0, 20, 16);   

       /* draw first planet */
       glPushMatrix();
           glRotatef ((GLfloat) year1, 0.0, 1.0, 0.0);
           glTranslatef (2.0, 0.0, 0.0);
           glRotatef ((GLfloat) day1, 0.0, 1.0, 0.0);
           glutWireSphere(0.2, 10, 8);    
       glPopMatrix();

       /* draw second planet */
       glPushMatrix();
           glRotatef ((GLfloat) year2, 0.0, 1.0, 0.0);
           glTranslatef (5.0, 0.0, 0.0);

            /* draw moon */
           glPushMatrix();
               glRotatef ((GLfloat) month, 0.0, 1.0, 0.0);
               glTranslatef (1.5, 0.0, 0.0);
               glutWireSphere(0.1, 10, 8);    
           glPopMatrix();

           glRotatef ((GLfloat) day2, 0.0, 1.0, 0.0);
           glutWireSphere(0.5, 12, 10); 
       glPopMatrix();

   glPopMatrix();
   glutSwapBuffers();
}

void reshape (int w, int h)
{
   glViewport (0, 0, (GLsizei) w, (GLsizei) h); 

}

void keyboard (unsigned char key, int x, int y)
{

   int current_width = glutGet(GLUT_WINDOW_WIDTH);
   int current_height = glutGet(GLUT_WINDOW_HEIGHT);
   switch (key) {
      case 'd':
         day1 = (day1 + d_day1) % 360;
         day2 = (day2 + d_day2) % 360;
         glutPostRedisplay();
         break;
      case 'D':
         day1 = (day1 - d_day1) % 360;
         day2 = (day2 - d_day2) % 360;
         glutPostRedisplay();
         break;
      case 'y':
         year1 = (year1 + d_year1) % 360;
         year2 = (year2 + d_year2) % 360;
         month = (month + 10*d_year2) % 360;
         glutPostRedisplay();
         break;
      case 'Y':
         year1 = (year1 - d_year1) % 360;
         year2 = (year2 - d_year2) % 360;
         month = (month - 10*d_year2) % 360;
         glutPostRedisplay();
         break;
     case 'z':
         r = 0.5 * r;
         glutPostRedisplay();
         break;
      case 'Z':
         r = 2.0*r;
         glutPostRedisplay();
         break; 
      case 27:
         exit(0);
         break;
      default:
         break;
   }
}

void menuResponse(int value)
{
    keyboard(value, 0, 0);
}

int main(int argc, char** argv)
{
   int menu;

   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
   glutInitWindowSize (500, 500); 
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);

   menu=glutCreateMenu(menuResponse);
   glutAddMenuEntry("Increment Day (d)", 'd');
   glutAddMenuEntry("Decrement Day (D)", 'D');
   glutAddMenuEntry("Increment Year (y)", 'y');
   glutAddMenuEntry("Decrement year (Y)", 'Y');
   glutAddMenuEntry("Zoom in (z)", 'z');
   glutAddMenuEntry("Zoom out (Z)", 'Z');
   glutAddMenuEntry("Quit (esc)", 27);
   glutAttachMenu(GLUT_RIGHT_BUTTON);

   init ();
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape);
   glutKeyboardFunc(keyboard);
   glutMainLoop();
   return 0;
}
